<script setup lang="ts">
  import { ref, StyleValue, useSlots, computed } from "vue";
  type fun = () => (Promise<any> | any);
  interface Props {
    title?: string;
    titleClass?: string[] | string;
    close?: fun;
    clickMaskClose?: boolean;
    confirm?: fun;
    showConfirm?: boolean;
    cancel?: fun;
    showCancel?: boolean;
    class?: string[] | string;
    style?: StyleValue;
    scrollX?: boolean;
    scrollY?: boolean;
    upperThreshold?: number | string; //	50	距顶部/左边多远时（单位px），触发 scrolltoupper 事件	
    lowerThreshold?: number | string; // 50 距底部/右边多远时（单位px），触发 scrolltolower 事件 
    scrollTop?: number | string; // 设置竖向滚动条位置 
    scrollLeft?: number | string; // 设置横向滚动条位置 
    scrollIntoView?: string; // 值应为某子元素id（id不能以数字开头）。设置哪个方向可滚动，则在哪个方向滚动到该元素 
    scrollWithAnimation?: boolean; // false 在设置滚动条位置时使用动画过渡 
    enableBackToTop?: boolean; // false iOS点击顶部状态栏、安卓双击标题栏时，滚动条返回顶部，只支持竖向 appNvue，微信小程序
    showScrollbar?: boolean; // false 控制是否出现滚动条 AppNvue 2.1.5+
    refresherEnabled?: boolean; // false 开启自定义下拉刷新 H5、appVue 2.5.12+,微信小程序基础库2.10.1+
    refresherThreshold?: number; // 45 设置自定义下拉刷新阈值 H5、appVue 2.5.12+,微信小程序基础库2.10.1+
    refresherDefaultStyle?: string; // "black" 设置自定义下拉刷新默认样式，支持设置 black，white，none，none 表示不使用默认样式 H5、appVue 2.5.12+,微信小程序基础库2.10.1+
    refresherBackground?: string; // "#FFF" 设置自定义下拉刷新区域背景颜色 H5、appVue 2.5.12+,微信小程序基础库2.10.1+
    refresherTriggered?: boolean; // false 设置当前下拉刷新状态，true 表示下拉刷新已经被触发，false 表示下拉刷新未被触发 H5、appVue 2.5.12+,微信小程序基础库2.10.1+
    enableFlex?: boolean; // false 启用 flexbox 布局。开启后，当前节点声明了 display: flex 就会成为 flex container，并作用于其孩子节点。 微信小程序 2.7.3
    scrollAnchoring?: boolean;
  }
  const
    props = withDefaults(defineProps<Props>(), { scrollY: true, clickMaskClose: true }),
    show = ref(false),
    elScrollView = ref(),
    emit = defineEmits<{
      (e: "scrolltoupper"): void;
      (e: "scrolltolower"): void;
      (e: "scroll"): void;
      (e: "refresherpulling"): void;
      (e: "refresherrefresh"): void;
      (e: "refresherrestore"): void;
      (e: "refresherabort"): void;
      (e: "close"): void;
      (e: "confirm"): void;
      (e: "cancel"): void;
    }>(),
    slots = useSlots(),
    tcfg = ref<any>({}),
    cfg = computed(() => {
      return Object.assign({}, props, tcfg.value) as Props;
    })
    ;

  async function close(e?: MouseEvent) {
    if (cfg.value.clickMaskClose) {
      if (cfg.value.close instanceof Function) {
        show.value = !!(await cfg.value.close());
      } else {
        emit("close");
        show.value = false;
      }
    }
    if (e && e.stopPropagation instanceof Function) {
      e.stopPropagation();
    }
    return show.value;
  }
  async function clickConfirm(e?: MouseEvent) {
    if (cfg.value.confirm instanceof Function) {
      show.value = !!(await cfg.value.confirm());
    } else {
      emit("confirm");
      show.value = false;
    }
    if (e && e.stopPropagation instanceof Function) {
      e.stopPropagation();
    }
  }
  async function clickCancel(e?: MouseEvent) {
    let r = true;
    if (cfg.value.cancel instanceof Function) {
      r = !!(await cfg.value.cancel());
    } else {
      emit("cancel");
      r = false;
    }
    show.value = !!(await close()) || r;
    if (e && e.stopPropagation instanceof Function) {
      e.stopPropagation();
    }
  }

  async function open(p?: Props) {
    if (p) { tcfg.value = p; }
    show.value = true;
  }
  defineExpose({ open, elScrollView });
  function click(e: MouseEvent) {
    e.stopPropagation instanceof Function && e.stopPropagation();
}
  function stop() {
    
  }
</script>
<template>
  <view class="Dialog whf ycc" v-if="show" @click.stop="close">
    <view class="content p04em y" @click="click">
      <view class="header txt-hid mb04em nbx" :class="cfg.titleClass" v-if="!!cfg.title && !slots.header">
        {{ cfg.title }}
      </view>
      <slot name="header" />
      <scroll-view ref="elScrollView" class="oh fg1" :class="cfg.class" :style="cfg.style" :scrollX="cfg.scrollX"
        :scrollY="cfg.scrollY" :upperThreshold="cfg.upperThreshold" :lowerThreshold="cfg.lowerThreshold"
        :scrollTop="cfg.scrollTop" :scrollLeft="cfg.scrollLeft" :scrollIntoView="cfg.scrollIntoView"
        :scrollWithAnimation="cfg.scrollWithAnimation" :enableBackToTop="cfg.enableBackToTop"
        :showScrollbar="cfg.showScrollbar" :refresherEnabled="cfg.refresherEnabled"
        :refresherThreshold="cfg.refresherThreshold" :refresherDefaultStyle="cfg.refresherDefaultStyle"
        :refresherBackground="cfg.refresherBackground" :refresherTriggered="cfg.refresherTriggered"
        :enableFlex="cfg.enableFlex" :scrollAnchoring="cfg.scrollAnchoring" @scrolltoupper="emit('scrolltoupper')"
        @scrolltolower="emit('scrolltolower')" @scroll="emit('scroll')" @refresherpulling="emit('refresherpulling')"
        @refresherrefresh="emit('refresherrefresh')" @refresherrestore="emit('refresherrestore')"
        @refresherabort="emit('refresherabort')" @click.stop="stop">
        <slot name="default" />
      </scroll-view>
      <slot name="footer" />
      <view class="footer x oh nbx mt04em"
        v-if="!!cfg.cancel || !!cfg.showCancel || !!cfg.confirm || !!cfg.showConfirm">
        <button v-if="!!cfg.cancel || !!cfg.showCancel" size="mini" class="cancel" @click="clickCancel">取消</button>
        <button v-if="!!cfg.confirm || !!cfg.showConfirm" size="mini" class="confirm" @click="clickConfirm">确定</button>
      </view>
    </view>
  </view>
</template>
<style lang="scss" scoped>
  .Dialog {
    position: fixed;
    top: 0;
    left: 0;
    background-color: $uni-bg-color-mask;
    z-index: 100;
    >.content {
      background-color: $uni-bg-color-grey;
      width: 80%;
      height: 50%;
      border-radius: 0.4em;
      >.header {
        color: $uni-color-title;
      }
      >.footer {
        >button {
          width: 49%;
          color: #FFFFFF;
        }
        >button::after {
          border: none;
        }
        >.cancel {
          background-color: $uni-color-primary;
          color: $uni-text-color-inverse;
        }
        >.confirm {
          background-color: $uni-color-success;
        }
      }
    }
  }
</style>